﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using blackhouse.Web.FasterFiles;
using System.Reflection;
using System.Configuration;
using System.Globalization;

namespace blackhouse.JavaScript.JQuery {
    public class JQueryLibraries {

        #region Fields

        private FasterFilesProvider files = new FasterFilesProvider();
        private List<string> forceIncluded = new List<string>();

        #endregion

        #region Properties

        private bool Debug {
            get {
#if DEBUG
                return true;
#else            
        return false;
#endif
            }
        }

        #endregion

        #region Methods

        private bool IsNotDisabled(string function) {
            string value = ConfigurationManager.AppSettings["JQueryLibraries." + function];
            if (string.IsNullOrEmpty(value)) return true;
            return value != "false";
        }

        public void IncludeJQueryMain() {
            this.IncludeJQueryMain(false);
        }

        public void IncludeJQueryMain(bool forceIncluded) {
            if (forceIncluded || this.IsNotDisabled("IncludeJQueryMain"))
                if (Debug)
                    files.AddJsFile(typeof(JQueryLibraries), "blackhouse.JavaScript.JQuery.jquery.js");
                else
                    files.AddJsFile(typeof(JQueryLibraries), "blackhouse.JavaScript.JQuery.jquery.min.js");
        }

        /// <summary>
        /// Dodaje referencję do UI, style do Jquery UI trzeba dołączyć samemu.
        /// </summary>
        public void IncludeJQueryUI() {
            this.IncludeJQueryUI(false);
        }

        /// <summary>
        /// Dodaje referencję do UI, style do Jquery UI trzeba dołączyć samemu.
        /// </summary>
        /// <param name="forceIncluded">Domyślnie można wyłączyć dołączanie UI poprzez wpis w configu: JQueryLibraries.IncludeJQueryUI = false. Jeżeli taki wpis będzie w configu to przekazując jako parametr true wymuszamy ingorowanie configa</param>
        public void IncludeJQueryUI(bool forceIncluded) {
            if (forceIncluded || this.IsNotDisabled("IncludeJQueryUI"))
                this.IncludeJQueryLocalLibrary("jquery-ui-1.10.3.js");
        }

        public void IncludeJQueryValidate() {
            this.IncludeJQueryLocalLibrary("jquery.metadata.js");
            this.IncludeJQueryLocalLibrary("jquery.validate.min.js", false);
        }

        public void IncludeJQueryPrettyPhoto() {
            this.IncludeJQueryLocalLibrary("jquery.prettyPhoto.js");
        }

        public void IncludeJQueryColor() {
            this.IncludeJQueryLocalLibrary("jquery.color.plus-names-2.1.1.min.js", false);
        }

        public void IncludeJQueryPrettyFileInput() {
            this.IncludeJQueryLocalLibrary("jquery.file-input.js");
        }

        public void IncludeJQueryWaypoints() {
            this.IncludeJQueryLocalLibrary("jquery.waypoints.min.js", false);
        }

        public void IncludeJQueryPreloaderPage() {
            this.IncludeJQueryLocalLibrary("jquery.preloadpage.js");
        }

        public void IncludeJQueryPrettySelect() {
            this.IncludeJQueryLocalLibrary("jquery.pretty.select.js");
        }

        public void IncludeJQuerySort() {
            this.IncludeJQueryLocalLibrary("jquery.tinysort.js");
        }

        public void IncludeJQueryMessages() {
            this.IncludeJQueryEasing();
            this.IncludeJQueryLocalLibrary("messages.js");
        }

        public void IncludeJQueryAjaxFileUpload() {
            this.IncludeJQueryLocalLibrary("jquery.ajaxfileupload.js");
        }

        public void IncludeJQueryCheckboxes() {
            this.IncludeJQueryLocalLibrary("checkbox.js");
        }

        public void IncludeJQueryEasing() {
            this.IncludeJQueryLocalLibrary("jquery.animation.easing.js");
            this.IncludeJQueryLocalLibrary("jquery.animation.easing.compatibility.js");
        }

        public void IncludeJQueryInputMask() {
            this.IncludeJQueryLocalLibrary("jquery.maskedinput.js");
        }

        public void IncludeJQueryOnlyNumber() {
            this.IncludeJQueryLocalLibrary("my.inputfilter.js");
        }

        public void IncludeJQueryFontAvalible() {
            this.IncludeJQueryLocalLibrary("jquery.fontavailable.min.js");
        }

        public void IncludeJQueryTimer() {
            this.IncludeJQueryLocalLibrary("jquery.timers.js");
        }

        [Obsolete("Aktualnie funkcjonalność dostępna z poziomu CSS")]
        public void IncludeJQueryDropShadow() {
            this.IncludeJQueryLocalLibrary("jquery.dropshadow.js");
        }

        [Obsolete("Toltipy robi się teraz inaczej")]
        public void IncludeJQueryTooltip() {
            this.IncludeJQueryTimer();
            //this.IncludeJQueryDropShadow();
            files.AddJsFile(typeof(JQueryLibraries), "blackhouse.JavaScript.JQuery.mbTooltip.js");
        }

        public void IncludeJQueryCookie() {
            this.IncludeJQueryLocalLibrary("jquery.cookie.js");
        }

        public void IncludeJQueryImagePreloader() {
            this.IncludeJQueryLocalLibrary("jquery.preload-image.js");
        }

        public void IncludeJQueryKeyFilter() {
            this.IncludeJQueryLocalLibrary("jquery.keyfilter.js");
        }

        public void IncludeJQueryCrop() {
            this.IncludeJQueryColor();
            this.IncludeJQueryLocalLibrary("jquery.Jcrop.min.js", false);
        }

        public void IncludeJQueryMouseWheel() {
            //this.IncludeJQueryMigrateSupport();
            this.IncludeJQueryLocalLibrary("jquery.mousewheel.js");
        }

        public void IncludeJQueryScrollAnimation() {
            this.IncludeJQueryLocalLibrary("jquery.scroll.animation.js");
        }

        public void IncludeJQueryBgIFrame() {
            this.IncludeJQueryLocalLibrary("jquery.bgiframe.js");
        }

        public void IncludeJQueryTemplate() {
            this.IncludeFileBasedOnJQuery("jquery.template.js");
        }

        public void IncludeJQueryPosition() {
            this.IncludeJQueryLocalLibrary("jquery.ui.position.js");
        }

        /// <summary>
        /// Jeżeli chcesz używać tooltipa, musisz go ostylować: zobacz przykładowy plik css -> blackhouse.JavaScript.JQuery.jTooltip-examples
        /// </summary>
        public void IncludeJQueryJTooltip() {
            this.IncludeJQueryBgIFrame();
            this.IncludeJQueryTemplate();
            this.IncludeJQueryPosition();
            this.IncludeJQueryLocalLibrary("jquery.jtooltip.js");
        }

        public void IncludeJQueryTools() {
            this.IncludeJQueryLocalLibrary("jquery.tools.min.js", false);
        }

        public void IncludeJQueryTipsy() {
            this.IncludeJQueryLocalLibrary("jquery.tipsy.js");
        }

        public void IncludeJQueryForm() {
            this.IncludeJQueryLocalLibrary("jquery.form.js");
        }

        public void IncludeJQueryMultiSelect() {
            this.IncludeJQueryMultiSelect(false);
        }

        public void IncludeJQueryMultiSelect(bool includeFilter) {
            this.IncludeJQueryUI();
            this.IncludeJQueryLocalLibrary("jquery.multiselect.js");
            this.IncludeJQueryLocalLibrary("jquery.multiselect.css.js");
            if (includeFilter) {
                this.IncludeJQueryLocalLibrary("jquery.multiselect.css.filter.js");
                this.IncludeJQueryLocalLibrary("jquery.multiselect.filter.js");
            }
        }

        public void IncludeJQuerySlimBox() {
            this.IncludeJQueryLocalLibrary("slimbox2.js");
        }

        public void IncludeJQueryFancybox() {
            this.IncludeJQueryLocalLibrary("jquery.fancybox.js");
            this.IncludeJQueryEasing();
            this.IncludeJQueryMouseWheel();
        }

        public void IncludeJQueryTemplates() {
            this.IncludeJQueryLocalLibrary("jquery.tmpl.js");
        }

        public void IncludeJQueryColorPicker() {
            this.IncludeJQueryLocalLibrary("colorpicker.js");
        }

        public void IncludeJQueryDateFormat() {
            this.IncludeJQueryLocalLibrary("date.format.js");
        }

        public void IncludeJQueryScrollPane() {
            this.IncludeJQueryMouseWheel();
            this.IncludeJQueryLocalLibrary("jquery.jscrollpane.js");
        }

        public void IncludeJQueryBlockUI() {
            this.IncludeJQueryLocalLibrary("jquery.blockUI.js");
        }

        [Obsolete("Błąd w sztuce?")]
        public void IncludeJQueryMigrateSupport() {
            this.IncludeJQueryLocalLibrary("jquery.migrate.js");
        }

        public void IncludeJQueryRotator() {
            this.IncludeJQueryLocalLibrary("rotator.js");
        }

        public void IncludeJQueryResponse() {
            this.IncludeJQueryLocalLibrary("css3-mediaqueries.js");
        }

        public void IncludeJQueryUICulture(CultureInfo culture) {
            if (!culture.IsNeutralCulture)
                culture = culture.Parent;
            this.IncludeJQueryLocalLibrary("jquery.ui.datepicker-" + culture.Name + ".js");
            files.AddAfterScript("$.datepicker.setDefaults($.datepicker.regional['" + culture.Name + "']);");
        }

        public void IncludeJQueryValidationEngine(CultureInfo culture) {
            if (!culture.IsNeutralCulture)
                culture = culture.Parent;
            this.IncludeJQueryLocalLibrary("ValidationEngine.Languages.jquery.validationEngine-" + culture.Name.ToLower() + ".js");
            this.IncludeJQueryLocalLibrary("jquery.validationEngine.js");
        }

        public void IncludeJSExtensions() {
            if (Debug)
                this.IncludeJSFile("blackhouse.Javascript.JQuery.extensions.js,blackhouse.Javascript");
            else
                this.IncludeJSFile("blackhouse.Javascript.JQuery.extensions.min.js,blackhouse.Javascript");
        }

        /// <summary>
        /// Ładuje bibliotekę z blackhouse.JavaScript.JQuery
        /// </summary>
        /// <param name="libraryName">Nazwa biblioteki: nazwa pliku z katalogu JQuery. Plik musi posiadać skompresowaną wersję .min.js</param>
        private void IncludeJQueryLocalLibrary(string libraryName) {
            this.IncludeJQueryLocalLibrary(libraryName, true);
        }

        /// <summary>
        /// Ładuje bibliotekę z blackhouse.JavaScript.JQuery
        /// </summary>
        /// <param name="libraryName">Nazwa biblioteki: nazwa pliku z katalogu JQuery</param>
        /// <param name="supportMinFile">Czy biblioteka posiada wersję skompresowaną (wersję .min.js)</param>
        private void IncludeJQueryLocalLibrary(string libraryName, bool supportMinFile) {
            string library = "blackhouse.JavaScript.JQuery." + libraryName.Substring(0, libraryName.Length - 3);
            if (!Debug && supportMinFile)
                library += ".min";
            library += ".js, blackhouse.JavaScript";
            this.IncludeFileBasedOnJQuery(library);
        }

        public void IncludeFileBasedOnJQuery(string file) {
            this.IncludeFileBasedOnJQuery(file, false);
        }

        public void IncludeFileBasedOnJQuery(string file, bool supportMinFile) {
            if (supportMinFile) {
                string[] assFileParts = file.Split(',');
                assFileParts[0] = assFileParts[0].Substring(0, assFileParts[0].Length - 3);
                if (!Debug && supportMinFile)
                    assFileParts[0] += ".min";
                file = assFileParts[0] + ".js," + assFileParts[1];
            }
            this.IncludeFileBasedOnJQuery(file, false, "");
        }
        /// <summary>
        /// Dodaje plik który korzysta z jQuery
        /// </summary>
        /// <param name="file">Plik w zapisie SOURCE,ASSEMBLY</param>
        public void IncludeFileBasedOnJQuery(string file, bool forceIncluded, string function) {
            this.IncludeJQueryMain(forceIncluded);
            if (forceIncluded || this.IsNotDisabled(function))
                this.IncludeJSFile(file);
        }

        private void IncludeJSFile(string file) {
            string[] fileParts = file.Split(',');
            if (fileParts.Length == 2) {
                try {
                    Assembly ass = Assembly.Load(fileParts[1]);
                    if (ass != null) {
                        Type type = ass.GetTypes()[0];
                        if (type != null) {
                            files.AddJsFile(type, fileParts[0]);
                        }
                    }
                } catch (Exception e) {
                    System.Diagnostics.Trace.Write(e, "Error");
                }
            }
        }

        #endregion

    }
}